package com.qishanor.system.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qishanor.framework.constant.CommonConstant;
import com.qishanor.framework.constant.enums.MenuTypeEnum;
import com.qishanor.system.mapper.SysMenuMapper;
import com.qishanor.system.model.SysMenu;
import com.qishanor.system.service.SysMenuService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @description: 菜单表 服务实现类
 * @author: 周振林
 * @date: 2022-04-09
 * @Copyright: 博客：http://www.zhouzhenlin.com - 沉淀、分享、成长、让自己和他人都有所收获
 **/

@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Override
    public List<Tree<Integer>> filterMenu(Set<SysMenu> all, String type, Integer parentId) {
        List<TreeNode<Integer>> collect = all.stream().filter(menuTypePredicate(type)).map(getNodeFunction()).collect(Collectors.toList());
        Integer parent = parentId == null ? CommonConstant.MENU_TREE_ROOT_ID : parentId;
        return TreeUtil.build(collect, parent);
    }

    @Override
    public List<Tree<Integer>> getMenuTree(boolean lazy, Integer parentId) {
        if(!lazy){
            List<TreeNode<Integer>> collect=baseMapper.selectList(Wrappers.lambdaQuery(SysMenu.class).orderByAsc(SysMenu::getSort))
                    .stream().map(getNodeFunction()).collect(Collectors.toList());
            return TreeUtil.build(collect,CommonConstant.MENU_TREE_ROOT_ID);
        }
        Integer parent=parentId==null?CommonConstant.MENU_TREE_ROOT_ID:parentId;
        List<TreeNode<Integer>> collect=baseMapper.selectList(Wrappers.lambdaQuery(SysMenu.class).eq(SysMenu::getParentId,parent).orderByAsc(SysMenu::getSort))
                .stream().map(getNodeFunction()).collect(Collectors.toList());

        return TreeUtil.build(collect,parent);
    }

    private Function<SysMenu, TreeNode<Integer>> getNodeFunction() {
        return menu -> {
            TreeNode<Integer> node = new TreeNode<>();
            node.setId(menu.getId());
            node.setName(menu.getName());
            node.setParentId(menu.getParentId());
            node.setWeight(menu.getSort());
            // 扩展属性
            Map<String, Object> extra = new HashMap<>();
            extra.put("icon", menu.getIcon());
            extra.put("path", menu.getPath());
            extra.put("component",menu.getComponent());
            extra.put("type", menu.getType());
            extra.put("permission", menu.getPermission());
            extra.put("label", menu.getName());
            extra.put("sort", menu.getSort());
            extra.put("keepAlive", menu.getKeepAlive());
            node.setExtra(extra);
            return node;
        };
    }
    /**
     * menu 类型断言
     * @param type 类型
     * @return Predicate
     */
    private Predicate<SysMenu> menuTypePredicate(String type) {
        return vo -> {
            if (MenuTypeEnum.TOP_MENU.getDescription().equals(type)) {
                return MenuTypeEnum.TOP_MENU.getType().equals(vo.getType());
            }
            // 其他查询 左侧 + 顶部
            return !MenuTypeEnum.BUTTON.getType().equals(vo.getType());
        };
    }
}
